package top.zhangjianyong.utils.coding;

import top.zhangjianyong.utils.constant.Constant;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;

/**
 * @program: topzhangjianyongutils
 * @description: MD5加密工具
 * @author: 张建勇
 * @create: 2019-03-18 09:56
 **/
public class MD5Util {


    /**
     * map MD5签名
     *
     * @param map
     * @return
     */
    public static String crypt(Map map) {
        Object[] keys = map.keySet().toArray();
        Arrays.sort(keys);
        StringBuilder sb = new StringBuilder();
        for (Object o : keys) {
            if (!"userId".equals(o))
                sb.append(map.get(o));
        }
        sb.append(Constant.MD5_KEY);
        return crypt(sb.toString()).toUpperCase();
    }

    /**
     * Encodes a string 2 MD5
     *
     * @param str String to encode
     * @return Encoded String
     * @throws NoSuchAlgorithmException
     */
    public static String crypt(String str) {
        if (str == null || str.length() == 0) {
            throw new IllegalArgumentException("String to encript cannot be null or zero length");
        }
        StringBuffer hexString = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] hash = md.digest();
            for (int i = 0; i < hash.length; i++) {
                if ((0xff & hash[i]) < 0x10) {
                    hexString.append("0" + Integer.toHexString((0xFF & hash[i])));
                } else {
                    hexString.append(Integer.toHexString(0xFF & hash[i]));
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hexString.toString();
    }

    /**
     * 对字符串md5加密
     *
     * @param str
     * @return
     * @throws Exception
     */
    public static String getMD5Str(String str) throws Exception {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            throw new Exception("MD5加密出现错误，" + e.toString());
        }
    }


    public static void main(String[] args) {
        try {
            System.out.println(getMD5Str("123").toUpperCase());
            System.out.println(crypt("123").toUpperCase());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
